package minidb.semantic;
import minidb.parse.exps.*;
import java.util.*;
import minidb.querycondition.*;

public class DeleteChecker extends CheckerBase
{
	private DeleteExp deleteExp;
	private String tableName;
	private List<Predicate> predicateList;

	public DeleteChecker(DeleteExp e)
	{
		super();
		this.deleteExp=e;
		this.tableName = e.tableName;
		if (e.queryCondition.condition != null)
			this.predicateList = e.queryCondition.condition.GetPredicateList();
		else
			this.predicateList = null;
	}

	//eat not no querycondtion 
	private void BeforeDeleteCheck()
	{
		if(this.predicateList!=null)
			this.deleteExp.queryCondition.condition=Conditioner.EatNot(this.deleteExp.queryCondition.condition);
	}
	
	@Override
	public Boolean DoSemanticCheck() throws SemanticException
	{
		this.BeforeDeleteCheck();
		
		// check tabal existence 
		if(!super.TableExists(this.tableName))
			throw new SemanticException(String.format("There is no table '%s'", this.tableName));
		
		// check field - table on querycondition 
		if (this.predicateList != null)
		{
			for (Predicate p : this.predicateList)
			{
				if (OperandField.class.isInstance(p.operand1))
				{
					Field f = ((OperandField) p.operand1).field;
					if (!super.Field_Table_OK(f, this.tableName))
						throw new SemanticException(String.format("There is no field '%s' in table '%s'", f.fieldName,
								this.tableName));
				}
				if (OperandField.class.isInstance(p.operand2))
				{
					Field f = ((OperandField) p.operand2).field;
					if (!super.Field_Table_OK(f, this.tableName))
						throw new SemanticException(String.format("There is no field '%s' in table '%s'", f.fieldName,
								this.tableName));
				}
			}
		}
		
		// check predicate type match on querycondtion 
		if (this.predicateList != null)
		{
			for (Predicate p : this.predicateList)
			{
				if (!super.Predicate_TYPEOK(p))
					throw new SemanticException(String.format("Predicate type not match on '%s'", p.Print_Base()));
			}
		}
		
		return true;
	}
}
